package com.vercon.moensmart.utils;

import android.content.Context;
import android.provider.Settings;
import android.text.TextUtils;

import com.vercon.common.utils.APPUtil;
import com.vercon.common.utils.LogUtils;
import com.vercon.moensmart.MainApplication;
import com.vercon.moensmart.mode.MenuStateBean;
import com.vercon.serialportlibrary.listener.OnOpenSerialPortListener;

import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by csh on 2021/11/26
 *  *  * 1.单色灯  都是pwn的方式，控制的灯光
 *  *  *2.双色灯  pwn和串口同时发送，如果是固件"20211015","20211208"，这两个版本，串口号使用AS2，其他的都使用AS0
 *   *  S系列灯光
 *  * 1.单色灯  都是pwn的方式，控制的灯光
 *  * 2.双色灯  波特率115200 串口是RGB命令 串口号/dev/ttyS3
 */
public class LightHelper {

    private final String TAG = getClass().getSimpleName();
    private SerialPortControl mControl;//串口工具

    private String serialPortNew = "/dev/ttyAS0";//新串口（r818版本主板）
    private final String SETTING_PWM = "setting_system_pwm";// value: 0~40000
    private final int baudrate = 115200;
    private final String SETTING_PWM3 = "setting_system_pwm3";//value:
    private final int maxLight = 40000;//单色灯最大调节度
    private static final String[] FirmwareVersion = {"20211015","20211208"};//以前出货一款这样的，旧版本固件，双色灯是串口
    private final  int pwm_num = 157;//40000/255 得到的（这个是因为，双色灯的话，有串口的，串口的数据的话，固定0-255）
    private final  int pwm_num_one = 400;//40000/100 得到的 这是单色灯的

    private static final LightHelper INSTANCE = new LightHelper();
    private boolean isSend= true;//是否发生数据
    private String saveCommad = "";//这是串口出问题之后保存的命令，重发一次

    public static LightHelper getInstance() {
        return INSTANCE;
    }

    private LightHelper() {
        for (int i = 0;i < FirmwareVersion.length;i++){
            if (FirmwareVersion[i].equals(APPUtil.getFirmwareVersion())){
                serialPortNew = "/dev/ttyAS2";//旧串口
                break;
            }
        }
        if (!MainApplication.Companion.isLightKiller()){
            // baudrate = 9600;
            serialPortNew = "/dev/ttyS3";
        }
    }

    public void initLightData(){
        MenuStateBean menuStateBean = PreferenceUtils.getMenuState();
        if(menuStateBean == null){
            PreferenceUtils.setData(PreferenceUtils.MenuState,new MenuStateBean(false,50,127));
        }
    }

    public void close_Open(boolean isSend){
        onDestroy();
        initPortControl(isSend);
    }

    /**
     * 是否，开启串口就发送命令
     * @param isSaveSend
     */
    private void initPortControl(boolean isSaveSend) {
        mControl = new SerialPortControl();
        //根据不同主板获取不同接口


        mControl.setOnDataReceiveListener(new SerialPortControl.OnDataReceiveListener() {
            @Override
            public void onDataReceive(byte[] bytes, int size) {
                isSend = true;
                saveCommad = "";
                //String data = ByteUtil.bytesToHexString(bytes);
                // LogUtils.v(TAG, "onDataReceived 接收消息: " + new String(bytes));
            }

            @Override
            public void onDataSent(byte[] bytes) {

                //  LogUtils.i(TAG, "onDataSent 发送消息: " + new String(bytes));
            }

            @Override
            public void onSuccess(String file) {
                LogUtils.d(TAG, "串口serialPortNew="+serialPortNew+"打开成功");
                if (isSaveSend) {
                    saveCommadSend();
                }
            }

            @Override
            public void onFail(String file, OnOpenSerialPortListener.Status status) {
                LogUtils.e(TAG, " onFail ");
            }
        });
        mControl.openSerialPort(serialPortNew, baudrate);

    }

//    private void againOpen(){
//        new Handler().postDelayed(new Runnable() {
//            @Override
//            public void run() {
//                if (!isSend) {
//                    LogUtils.e(TAG, "重新打开串口");
//                    initPortControl();
//                }
//            }
//        },200);
//    }

    /**
     * x 代表色温0-255  y 0-100%
     * 白灯 a = x*y%  黄灯 b = (255-x)*y%
     */
    private void sendData(int brightness,int colorData) {
        if (mControl == null){
            return;
        }
        String msg;
        double k = ((double) brightness) / 100;
        int b = (int) (colorData * k);
        int a = (int) ((255 - colorData) * k);
        LogUtils.e("a =" + a + "--b=" + b + "--brightness=" + brightness + "--colorData=" + colorData + "--k=" + k);
        String s_a = Integer.toHexString(a);
        String s_b = Integer.toHexString(b);
        if (s_a.length() == 1) {
            s_a = "0" + s_a;
        }
        if (s_b.length() == 1) {
            s_b = "0" + s_b;
        }
        msg = "a506ffa0" + s_a + s_b + "00ee5a";
        msg = msg.toUpperCase();
        saveCommad = msg;
        mControl.onSend(msg);

    }

    /**
     * 关灯
     */
    private void sendClose() {

        LogUtils.e("sendClose");
        saveCommad = "a506ffa00000ffee5a";
        if (mControl != null) {
            mControl.onSend("a506ffa00000ffee5a");
        }

    }

    /**
     * 新的RGB方式控灯
     */
    private void rgbsend(int brightness,int colorData) {

        String msg;
        double k = ((double) brightness) / 100; //最大值是255
        int a = (int) (colorData * k);
        int b = (int) ((255 - colorData) * k);
        a = getwhiteCommand(colorData,k);
        b = getwarnCommand(colorData,k);
        LogUtils.e("a =" + a + "--b=" + b + "--brightness=" + brightness + "--colorData=" + colorData + "--k=" + k);
        String s_a = Integer.toHexString(a);
        String s_b = Integer.toHexString(b);
        LogUtils.e("s_a=" + s_a+" s_b="+s_b);
        if (s_a.length() == 1) {
            s_a = "0" + s_a;
        }
        if (s_b.length() == 1) {
            s_b = "0" + s_b;
        }
        msg = "RGB" + s_a + s_b + "00";
        msg = msg.toUpperCase();
        LogUtils.e("msg=" + msg);
        msg = ByteUtil.str2HexStrnew(msg);
        saveCommad = msg;
        if (mControl != null){
            mControl.onSend(msg);
        }

    }

    /**
     * 获取白灯数据
     * @param color
     * @return
     */
    private int getwhiteCommand(int color,double y){
        int white = 0;
        if (color < 128){//50%
            white=(int)(2*(color*y));
        }else {
            white = (int)(255 * y);
        }
        return white;
    }
    /**
     * 获取暖灯数据
     * @param color
     * @return
     */
    private int getwarnCommand(int color,double y){
        int warn = 0;
        if (color < 128){//50%
            warn=(int)(255 * y);
        }else {
            warn = (int)(2*((255-color)*y));
        }
        return warn;
    }
    /** 获取白灯数据
     * @param color
     * @return
     */
    private int getwhitePWMCommand(int color,double y){
        int white = 0;
        if (color < 128){//50%
            white=(int)(maxLight-maxLight * y);
        }else {
            int aa = (255-color);
            LogUtils.e("aa =" + aa+" color/2="+255/2);
            white = (int)(maxLight-(aa*pwm_num*2 * y));
            LogUtils.e("warn =" + white);

        }
        return white;
    }
    /**
     * 获取暖灯数据
     * @param color
     * @return
     */
    private int getwarnPWMCommand(int color,double y){
        int warn = 0;
        if (color < 128){//50%
//            int aa = (color-255/2);
//            LogUtils.e("aa =" + aa+" color/2="+255/2);
            warn = (int)(maxLight-color*pwm_num*2 * y);
        }else {
            warn = (int)(maxLight-maxLight * y);
            LogUtils.e("white =" + warn);
        }
        return warn;
    }
    /**
     * 控制灯光  双色灯使用2个单色灯方式
     */
    /**
     * x 代表色温0-255  y 0-100%
     * 白灯 a = x*y%  黄灯 b = (255-x)*y%
     */
    private void twoLight( Context mContext,int brightness,int colorData) {
        double k = ((double) brightness) / 100;
        int a = (int) (maxLight-((maxLight - colorData*pwm_num)*k));
        int b = (int) (maxLight-((maxLight-((255 - colorData)*pwm_num))*k));
        a = getwhitePWMCommand(colorData,k);
        b = getwarnPWMCommand(colorData,k);
        a = getpwndata(a);
        b = getpwndata(b);
        LogUtils.e("a1 =" + a + "--b1=" + b + "--brightness=" + brightness + "--colorData=" + colorData + "--k=" + k);
        Settings.System.putInt(mContext.getContentResolver(), SETTING_PWM, a);//白灯
        Settings.System.putInt(mContext.getContentResolver(), SETTING_PWM3, b);//黄灯
    }
    /**
     * 发送保存的命令
     */
    private void saveCommadSend() {
        Observable.timer(500, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        LogUtils.e("mControl="+mControl+"--saveCommad="+saveCommad);
                        if (mControl == null || TextUtils.isEmpty(saveCommad)){
                            return;
                        }
                        mControl.onSend(saveCommad);
                    }
                });

    }
    /**
     * 关灯
     */
    private void rgbsendClose() {
        saveCommad = ByteUtil.str2HexStrnew("RGB000000");
        if (mControl != null) {
            mControl.onSend(ByteUtil.str2HexStrnew("RGB000000"));
        }
    }

    /**
     * k系列控制灯光
     * @param mContext
     * @param isShow_color
     * @param brightness
     * @param colorData
     */
    private void killer_light(Context mContext,boolean isShow_color,int brightness,int colorData){
        if (isShow_color) {
            rgbsend(brightness, colorData);
            twoLight(mContext, brightness, colorData);
        } else {//单色灯
            int value = (maxLight - brightness * pwm_num_one);
            LogUtils.e("单色灯=" + value);
            value = getpwndata(value);
            Settings.System.putInt(mContext.getContentResolver(), SETTING_PWM, value);
        }
    }
    /**
     * S系列控制灯光
     * @param isShow_color
     * @param brightness
     * @param colorData
     */
    private void S3288_light(boolean isShow_color,int brightness,int colorData){

        if (isShow_color) {//双色
            //sendData(brightness, colorData);
            rgbsend(brightness, colorData);
        }else {//单色灯
            //耗时操作
            if(isFastClick()){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String commend ;
                        int value1 = (maxLight - brightness * pwm_num_one);
                        commend = "echo " + (value1) + " > /sys/ex_ctl/pwm \n";
                        RootCmd.execRootCmd(commend);
                    }
                }).start();
            }
        }
    }

    /**
     * 控制灯光
     */
    public void controlLight(Context mContext,boolean light_switch_state,boolean isShow_color,int brightness,int colorData) {
        if (!light_switch_state) {
            return;
        }
        if (MainApplication.Companion.isLightKiller()) { //k系列
            killer_light(mContext,isShow_color,brightness,colorData);
        }else {
            S3288_light(isShow_color,brightness,colorData);
        }
        // saveDataState(false);
    }

    /**
     * 外面控制开启当前灯光
     */
    public void currentLight(Context mContext,boolean isShow_color,int brightness,int colorData) {
        againSend();
        if (MainApplication.Companion.isLightKiller()) { //k系列
            killer_light(mContext,isShow_color,brightness,colorData);
        }else {
            S3288_light(isShow_color,brightness,colorData);
        }

    }

    /**
     * 控制灯光关闭  light代表是不是app关闭后关灯 ,外面调用传true  ，里面使用传false
     */

    public void controlLightClose(Context mContext,boolean isShow_color) {
        LogUtils.e("controlLightClose");
        if (MainApplication.Companion.isLightKiller()) { //k系列
            if (isShow_color) {
                rgbsendClose();
                Settings.System.putInt(mContext.getContentResolver(), SETTING_PWM3, maxLight);
                Settings.System.putInt(mContext.getContentResolver(), SETTING_PWM, maxLight);
            } else {
                Settings.System.putInt(mContext.getContentResolver(), SETTING_PWM, maxLight);
            }
        }else {
            if (isShow_color) {//双色
                //sendClose();
                rgbsendClose();
            }else {//单色灯
                LogUtils.e("controlLightClose");
                String commend = "echo 40000 > /sys/ex_ctl/pwm \n";
                RootCmd.execRootCmd(commend);
            }
        }
        //saveDataState(light);
    }
    public void againSend(){
        isSend = false;
        saveCommad = "";
        Observable.timer(300, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        LogUtils.e("isSend="+isSend+"--saveCommad="+saveCommad);
                        if (!isSend && !TextUtils.isEmpty(saveCommad)){
                            close_Open(true);
                        }
                    }
                });
    }
    private int getpwndata(int a){
        if (a < 0){
            a = 0;
        }
        if (a > maxLight){
            a =  maxLight;
        }
        return  a ;
    }
    private  long lastClickTime = 0;
    private  final int CLICK_TIME = 80; //快速点击间隔时间

    // 判断按钮是否快速点击
    private  boolean isFastClick() {
        long time = System.currentTimeMillis();
        if (time - lastClickTime < CLICK_TIME) {//判断系统时间差是否小于点击间隔时间
            return true;
        }
        lastClickTime = time;
        return false;
    }
    public void onDestroy(){
        LogUtils.e("onDestroy");
        if (mControl != null) {
            mControl.closeSerialPort();
        }
    }
} 